package com.zky.seckillzky.seckill.controller;

import com.zky.common.utils.PageUtils;
import com.zky.common.utils.R;
import com.zky.seckillzky.seckill.entity.OrderEntity;
import com.zky.seckillzky.seckill.entity.SeckillGoodsEntity;
import com.zky.seckillzky.seckill.entity.UserEntity;
import com.zky.seckillzky.seckill.rabbit.MQSender;
import com.zky.seckillzky.seckill.rabbit.MiaoshaMessage;
import com.zky.seckillzky.seckill.redis.MiaoShaKey;
import com.zky.seckillzky.seckill.redis.RedisService;
import com.zky.seckillzky.seckill.service.GoodsService;
import com.zky.seckillzky.seckill.service.SeckillGoodsService;
import com.zky.seckillzky.seckill.service.SeckillOrderService;
import com.zky.seckillzky.seckill.vo.GoodsVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Arrays;
import java.util.List;
import java.util.Map;



/**
 * 秒杀活动表
 *
 * @author zky
 * @email zhongkaiyue@gmail.com
 * @date 2021-07-02 11:18:02
 * 秒杀控制器
 */
@Controller
@RequestMapping("seckill/seckillgoods")
public class SeckillGoodsController  implements InitializingBean {
//    implements InitializingBean
    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private SeckillOrderService seckillOrderService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MQSender mqSender;

    /**
     * 列表
     */
    @RequestMapping("/list")
//    @RequiresPermissions("seckill:seckillgoods:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = seckillGoodsService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{seckillId}")
//    @RequiresPermissions("seckill:seckillgoods:info")
    public R info(@PathVariable("seckillId") Long seckillId){
		SeckillGoodsEntity seckillGoods = seckillGoodsService.getById(seckillId);

        return R.ok().put("seckillGoods", seckillGoods);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
//    @RequiresPermissions("seckill:seckillgoods:save")
    public R save(@RequestBody SeckillGoodsEntity seckillGoods){
		seckillGoodsService.save(seckillGoods);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
//    @RequiresPermissions("seckill:seckillgoods:update")
    public R update(@RequestBody SeckillGoodsEntity seckillGoods){
		seckillGoodsService.updateById(seckillGoods);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
//    @RequiresPermissions("seckill:seckillgoods:delete")
    public R delete(@RequestBody Long[] seckillIds){
		seckillGoodsService.removeByIds(Arrays.asList(seckillIds));

        return R.ok();
    }

    /**
     * 项目启动时候会立刻执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
            List<SeckillGoodsEntity> goodsList= seckillGoodsService.queryAllSeckillGoods();
        for (SeckillGoodsEntity goods : goodsList) {
            redisService.set(MiaoShaKey.getGoodsCountKey,""+goods.getGoodsId(),goods.getSeckillNum());
        }
    }


    /**
     * 基于消息队列做秒杀
     * @param userEntity
     * @param goodsId
     * @param map
     * @return
     */
    @RequestMapping("/do_miaosha")
    public String domiaosha(UserEntity userEntity, Long goodsId, ModelMap map){
        if (null==userEntity){
            return "login";
        }
        GoodsVo goods = goodsService.queryGoodsByGoodsId(goodsId);
        //1.缓存里预减库存，库存小于0，返回错误信息，如果不小于继续后面的操作
        Long cachStock = redisService.decr(MiaoShaKey.getGoodsCountKey, "" + goodsId);//i--
        if (cachStock<=0){//<=-1
            return "miaosha_fail";
//            return R.ok().put("error","空存为空");
        }
        //2.检查当前用户是否已经秒杀过
//        SeckillOrderEntity seckorder =  seckillOrderService.queryOrderByUserIdAndGoodsId(userEntity.getUserId(),goodsId);
//        if (null!=seckorder){
//            map.put("errormsg","已经参与过秒杀了，不要再购买了");
//
//            return "miaosha_fail";
////            return R.ok().put("error","商品已经秒杀过");
//        }

        MiaoshaMessage mm = new MiaoshaMessage();
        mm.setGoodsId(goodsId);
        mm.setUser(userEntity);

        //消息队列准备入队
        mqSender.miaoshaSend(mm);
        OrderEntity orderInfo = seckillGoodsService.doMiaosha(userEntity,goods);
        map.put("goods",goods);
        map.put("orderInfo",orderInfo);

        return "order_detail";

    }



    /**
     * 解决超卖的问题
     * 1.数据库默认的锁机制保证库存唯一
     * 2.业务层加判断保证 订单不超卖
     * 3.数据库使用，用户id和商品id  作为唯一索引，保证同一个用户不要超卖
     * @param userEntity
     * @param goodsId
     * @param map
     * @return
     */
//    @RequestMapping("/do_miaosha")
//    public String domiaosha(UserEntity userEntity, Long goodsId, ModelMap map){
//        if (null==userEntity){
//            return "login";
//        }
//        /**
//         * 1.检查是否有库存
//         * 2.检查当前用户是否已经秒杀过
//         */
//        //1.检查是否有库存
//        GoodsVo goods = goodsService.queryGoodsByGoodsId(goodsId);
//        if (goods.getSeckillNum()<=0){
//            map.put("errormsg","已经没有库存了");
//
//            return "miaosha_fail";
//        }
//        //2.检查当前用户是否已经秒杀过
//        SeckillOrderEntity seckorder =  seckillOrderService.queryOrderByUserIdAndGoodsId(userEntity.getUserId(),goodsId);
//        if (null!=seckorder){
//            map.put("errormsg","已经参与过秒杀了，不要再购买了");
//
//            return "miaosha_fail";
//        }
//        // 3.减库存（miaosha_goods），生成订单详情，生成秒杀订单
//        OrderEntity orderInfo = seckillGoodsService.doMiaosha(userEntity,goods);// 1   2 3 456789
//
//        map.put("goods",goods);
//        map.put("orderInfo",orderInfo);
//
//
//        return "order_detail";
//    }




}
